

#include "NodeParentheses.h"

NodeParentheses::NodeParentheses(bool leftParentheses, bool rightParentheses)
: Node(QString("parentheses"), 1, QString("()"))
, m_leftParentheses(leftParentheses)
, m_rightParentheses(rightParentheses) {

    // add the layout
    QHBoxLayout* layout = new QHBoxLayout(this);
    layout->setSpacing(1);
    layout->setContentsMargins(1, 1, 1, 1);

    // set index to place child node at
    m_index = 0;

    // add the label (
    if (m_leftParentheses) {
        EditOperator* lab1 = new EditOperator(this);
        lab1->setObjectName("left_parentheses");
        lab1->setText("(");
        layout->addWidget(lab1);

        // set index to place child node at
        m_index = 1;
    }

    // add the label )
    if (m_rightParentheses) {
        EditOperator* lab2 = new EditOperator(this);
        lab2->setObjectName("right_parentheses");
        lab2->setText(")");
        layout->addWidget(lab2);
    }
}

QString NodeParentheses::toCasString() const {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "", "Expected one child.");

    QString str;
    str.append("(");
    str.append(getSingleChild()->toCasString());
    str.append(")");
    return str;
}

QString NodeParentheses::toPrintString() const {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "", "Expected one child.");

    QString str;
    str.append("(");
    if (getSingleChild()->getNodeType() == "empty") str.append("_");
    else str.append(getSingleChild()->toPrintString());
    str.append(")");
    return str;
}

QString NodeParentheses::toParseString() const {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "", "Expected one child.");

    QString str;
    if (m_leftParentheses) str.append("(");
    str.append(getSingleChild()->toParseString());
    if (m_rightParentheses) str.append(")");
    return str;
}

int NodeParentheses::getInputPosition(bool& found) const {
    int counter = 0;

    // look it left parentheses label/lineedit
    if (m_leftParentheses) {
        if (leftPar()->hasFocus() and not found) {
            found = true;
            counter += leftPar()->cursorPosition();
        } else if (not found) {
            counter += leftPar()->text().size();
        }
    }

    // pass to child node
    if (not found) counter += getSingleChild()->getInputPosition(found);

    // look it right parentheses label/lineedit
    if (m_rightParentheses) {
        if (rightPar()->hasFocus() and not found) {
            found = true;
            counter += rightPar()->cursorPosition();
        } else if (not found) {
            counter += rightPar()->text().size();
        }
    }

    return counter;
}

void NodeParentheses::setInputPosition(int& position) {
    Q_ASSERT_X(getSingleChild() != 0, "",
            "Could not find single child node.");
    Q_ASSERT_X(numChildren() == 1, "",
            "Expected one child.");

    // if position falls into left parentheses node place it
    if (m_leftParentheses) {
        if (position == 0 or position == 1) {
            leftPar()->setFocus();
            leftPar()->setCursorPosition(position);
        }
        --position;
    }

    if (position >= 0) getSingleChild()->setInputPosition(position);

    // if position falls into right parentheses node place it
    // but only if it has not been placed ie is greater then 0
    if (m_rightParentheses) {
        if (position == 1) {
            rightPar()->setFocus();
            rightPar()->setCursorPosition(position);
        }
        --position;
    }
}

EditOperator * NodeParentheses::leftPar() {
    Q_ASSERT_X(m_leftParentheses, "", "This parentheses does not have a left parentheses.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses"), "",
            "Unable to find left label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses")->text().size() == 1
            , "", "Left label size is not one.");
    return findDirectChild<EditOperator *>("left_parentheses");
}

EditOperator * NodeParentheses::rightPar() {
    Q_ASSERT_X(m_rightParentheses, "", "This parentheses does not have a right parentheses.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses"), "",
            "Unable to find right label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses")->text().size() == 1
            , "", "Right label size is not one.");
    return findDirectChild<EditOperator *>("right_parentheses");
}

const EditOperator * NodeParentheses::leftPar() const {
    Q_ASSERT_X(m_leftParentheses, "", "This parentheses does not have a left parentheses.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses"), "",
            "Unable to find left label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("left_parentheses")->text().size() == 1
            , "", "Left label size is not one.");
    return findDirectChild<EditOperator *>("left_parentheses");
}

const EditOperator * NodeParentheses::rightPar() const {
    Q_ASSERT_X(m_rightParentheses, "", "This parentheses does not have a right parentheses.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses"), "",
            "Unable to find right label.");
    Q_ASSERT_X(findDirectChild<EditOperator *>("right_parentheses")->text().size() == 1
            , "", "Right label size is not one.");
    return findDirectChild<EditOperator *>("right_parentheses");
}
